/*============================================================================
  File:      DmhAllocator.h
 
  Summary:   STL allocator class that uses the IDMMemoryAllocator interface
			 to allocate memory.

  Date:		 June 30, 2004
------------------------------------------------------------------------------
  This file is part of the Microsoft SQL Server Code Samples.
 
  Copyright (C) 2003 Microsoft Corporation.  All rights reserved.
 
This source code is intended only as a supplement to Microsoft
Development Tools and/or on-line documentation.  See these other
materials for detailed information regarding Microsoft code samples.
 
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
============================================================================*/

#pragma once
#include <vector>
#include "..\..\dmalgo.h" 
#include <atlcomcli.h>
#include <assert.h>
#include "DmhMemory.h"


template <class T>
class dmh_allocator
{
  public:

	typedef size_t    size_type;
	typedef ptrdiff_t difference_type;
	typedef T*        pointer;
	typedef const T*  const_pointer;
	typedef T&        reference;
	typedef const T&  const_reference;
	typedef T         value_type;

	DMHALLOC& _dmhalloc;

	dmh_allocator(DMHALLOC& dmhalloc) : _dmhalloc(dmhalloc)
	{
	}
  
	dmh_allocator(const dmh_allocator& dmhallocator) : _dmhalloc(dmhallocator._dmhalloc)
	{
	}

	pointer   allocate(size_type n, const void * = 0) 
	{
		assert(_dmhalloc._spidmmemoryallocator != NULL);

		byte* pb;

		_dmhalloc._spidmmemoryallocator->Alloc((UINT) n * sizeof(T), &pb);
         
		return (T*) pb;
	}

	void      deallocate(void* p, size_type) 
	{
		if (p) 
		{
			_dmhalloc._spidmmemoryallocator->Free((byte*) p);
		}
	}
	
	pointer           address(reference x) const 
	{ 
		return &x; 
	}

	const_pointer     address(const_reference x) const 
	{ 
		return &x; 
	}

	dmh_allocator<T>&  operator=(const dmh_allocator&) 
	{ 
		return *this; 
	}
  
	void              construct(pointer p, const T& val) 
	{ 
		new ((T*) p) T(val); 
	}

	void              destroy(pointer p) 
	{ 
		p->~T(); 
	}

	size_type         max_size() const 
	{ 
		return size_t(-1); 
	}

	template <class U>
	struct rebind 
	{ 
		typedef dmh_allocator<U> other; 
	};

	template <class U>
	dmh_allocator(const dmh_allocator<U>& dmhallocator) : _dmhalloc(dmhallocator._dmhalloc)
	{
	}

	template <class U>
	dmh_allocator& operator=(const dmh_allocator<U>&) 
	{ 
		return *this; 
	}
};
